Module modules.stag
File name: stag.py Author: Martin Jůda Python Version: 3.7 Description: Module responsible for communication with Stag API
Expand source code
"""
File name: stag.py
Author: Martin Jůda
Python Version: 3.7
Description: Module responsible for communication with Stag API
"""
import requests
from modules.constants import STAG_AUTH, STAG_BASE_URL
from modules.errors import NoActiveStudyError, StagUnavailableError
class StagCommunicator:
def get_active_studies(self, card_number):
"""Verify if active study exists for this card number and find student's ID
Args:
card_number (str): Card number
Returns:
list(dict): Detail about active studies and about student.
Raises:
StagUnavailableError: Connection to Stag API can not be established.
NoActiveStudyError: No active study for this card number.
"""
url = f"{STAG_BASE_URL}/student/getStudiaByCisloKarty"
params = dict(cisloKarty=card_number, outputFormat="json")
try:
study_report = self._send_get_request(
url=url, params=params, auth=STAG_AUTH
)
except requests.RequestException as err:
raise StagUnavailableError() from err
else:
return self._parse_active_study(study_report)
def get_completed_subjects_for_study(self, study, actual_year):
"""Get all completed subjects for selected study, skip subjects from actual year
because they may not be completed yet.
Args:
study (dict): info about study program
actual_year (datetime.year): Year for compare
Returns:
list(dict): List of completed subjects set
"""
url = f"{STAG_BASE_URL}/predmety/getPredmetyByStudent"
last_year = actual_year - 1
completed_subjects = []
params = dict(
osCislo=study["osCislo"], outputFormat="json", semestr="%", rok="%"
)
try:
response = self._send_get_request(url=url, params=params, auth=STAG_AUTH)
except requests.RequestException as err:
raise StagUnavailableError() from err
else:
subjects = response.get("predmetStudenta")
if subjects:
max_year = max([int(subject["rok"]) for subject in subjects])
if max_year in [actual_year, last_year]:
completed_subjects = [
{
"subject_code": f"{subject['katedra']}/"
f"{subject['zkratka']}",
**subject,
}
for subject in subjects
if (
subject.get("statut") == "A" or subject.get("statut") == "B"
)
and int(subject["rok"]) != max_year
]
else:
completed_subjects = [
{
"subject_code": f"{subject['katedra']}/"
f"{subject['zkratka']}",
**subject,
}
for subject in subjects
if (
subject.get("statut") == "A" or subject.get("statut") == "B"
)
]
# return only unique subjects because student could repeat the subject twice
return list({s["subject_code"]: s for s in completed_subjects}.values())
def get_study_codes_for_active_studies(self, active_studies):
"""Get study code for each active study
Args:
active_studies list(dict): active studies
Returns:
list(str): list of study codes
"""
study_codes = []
url = f"{STAG_BASE_URL}/student/getStudentInfo"
for study in active_studies:
params = dict(osCislo=study["osCislo"], outputFormat="json")
try:
response = self._send_get_request(
url=url, params=params, auth=STAG_AUTH
)
except requests.RequestException as err:
raise StagUnavailableError() from err
else:
study_codes.append(response.get("kodSp"))
return study_codes
@staticmethod
def _send_get_request(url, params=None, auth=None):
"""Send HTTP GET request to selected url
Args:
url (str): Destination URL
params (dict): Query parameters
auth (tuple): Basic HTTP authorization
Returns:
dict: data from json response
"""
response = requests.get(url=url, params=params, auth=auth)
response.raise_for_status()
return response.json()
@staticmethod
def _parse_active_study(study_report):
"""Pick active studies from all of student's studies
Args:
study_report (dict): Info about student's studies from Stag
Returns:
dict: Active studies.
Raises:
NoActiveStudyError: No active study found.
"""
active_studies = []
studies = study_report.get("studentShort")
if not studies:
raise NoActiveStudyError()
for study in studies:
if study.get("stav") == "S":
active_studies.append(study)
if active_studies:
return active_studies
raise NoActiveStudyError()
Classes
class StagCommunicator-
Expand source code
class StagCommunicator: def get_active_studies(self, card_number): """Verify if active study exists for this card number and find student's ID Args: card_number (str): Card number Returns: list(dict): Detail about active studies and about student. Raises: StagUnavailableError: Connection to Stag API can not be established. NoActiveStudyError: No active study for this card number. """ url = f"{STAG_BASE_URL}/student/getStudiaByCisloKarty" params = dict(cisloKarty=card_number, outputFormat="json") try: study_report = self._send_get_request( url=url, params=params, auth=STAG_AUTH ) except requests.RequestException as err: raise StagUnavailableError() from err else: return self._parse_active_study(study_report) def get_completed_subjects_for_study(self, study, actual_year): """Get all completed subjects for selected study, skip subjects from actual year because they may not be completed yet. Args: study (dict): info about study program actual_year (datetime.year): Year for compare Returns: list(dict): List of completed subjects set """ url = f"{STAG_BASE_URL}/predmety/getPredmetyByStudent" last_year = actual_year - 1 completed_subjects = [] params = dict( osCislo=study["osCislo"], outputFormat="json", semestr="%", rok="%" ) try: response = self._send_get_request(url=url, params=params, auth=STAG_AUTH) except requests.RequestException as err: raise StagUnavailableError() from err else: subjects = response.get("predmetStudenta") if subjects: max_year = max([int(subject["rok"]) for subject in subjects]) if max_year in [actual_year, last_year]: completed_subjects = [ { "subject_code": f"{subject['katedra']}/" f"{subject['zkratka']}", **subject, } for subject in subjects if ( subject.get("statut") == "A" or subject.get("statut") == "B" ) and int(subject["rok"]) != max_year ] else: completed_subjects = [ { "subject_code": f"{subject['katedra']}/" f"{subject['zkratka']}", **subject, } for subject in subjects if ( subject.get("statut") == "A" or subject.get("statut") == "B" ) ] # return only unique subjects because student could repeat the subject twice return list({s["subject_code"]: s for s in completed_subjects}.values()) def get_study_codes_for_active_studies(self, active_studies): """Get study code for each active study Args: active_studies list(dict): active studies Returns: list(str): list of study codes """ study_codes = [] url = f"{STAG_BASE_URL}/student/getStudentInfo" for study in active_studies: params = dict(osCislo=study["osCislo"], outputFormat="json") try: response = self._send_get_request( url=url, params=params, auth=STAG_AUTH ) except requests.RequestException as err: raise StagUnavailableError() from err else: study_codes.append(response.get("kodSp")) return study_codes @staticmethod def _send_get_request(url, params=None, auth=None): """Send HTTP GET request to selected url Args: url (str): Destination URL params (dict): Query parameters auth (tuple): Basic HTTP authorization Returns: dict: data from json response """ response = requests.get(url=url, params=params, auth=auth) response.raise_for_status() return response.json() @staticmethod def _parse_active_study(study_report): """Pick active studies from all of student's studies Args: study_report (dict): Info about student's studies from Stag Returns: dict: Active studies. Raises: NoActiveStudyError: No active study found. """ active_studies = [] studies = study_report.get("studentShort") if not studies: raise NoActiveStudyError() for study in studies: if study.get("stav") == "S": active_studies.append(study) if active_studies: return active_studies raise NoActiveStudyError()Methods
def get_active_studies(self, card_number)-
Verify if active study exists for this card number and find student's ID
Args
card_number:str- Card number
Returns
list(dict): Detail about active studies and about student.
Raises
StagUnavailableError- Connection to Stag API can not be established.
NoActiveStudyError- No active study for this card number.
Expand source code
def get_active_studies(self, card_number): """Verify if active study exists for this card number and find student's ID Args: card_number (str): Card number Returns: list(dict): Detail about active studies and about student. Raises: StagUnavailableError: Connection to Stag API can not be established. NoActiveStudyError: No active study for this card number. """ url = f"{STAG_BASE_URL}/student/getStudiaByCisloKarty" params = dict(cisloKarty=card_number, outputFormat="json") try: study_report = self._send_get_request( url=url, params=params, auth=STAG_AUTH ) except requests.RequestException as err: raise StagUnavailableError() from err else: return self._parse_active_study(study_report) def get_completed_subjects_for_study(self, study, actual_year)-
Get all completed subjects for selected study, skip subjects from actual year because they may not be completed yet.
Args
study:dict- info about study program
actual_year:datetime.year- Year for compare
Returns
list(dict): List of completed subjects set
Expand source code
def get_completed_subjects_for_study(self, study, actual_year): """Get all completed subjects for selected study, skip subjects from actual year because they may not be completed yet. Args: study (dict): info about study program actual_year (datetime.year): Year for compare Returns: list(dict): List of completed subjects set """ url = f"{STAG_BASE_URL}/predmety/getPredmetyByStudent" last_year = actual_year - 1 completed_subjects = [] params = dict( osCislo=study["osCislo"], outputFormat="json", semestr="%", rok="%" ) try: response = self._send_get_request(url=url, params=params, auth=STAG_AUTH) except requests.RequestException as err: raise StagUnavailableError() from err else: subjects = response.get("predmetStudenta") if subjects: max_year = max([int(subject["rok"]) for subject in subjects]) if max_year in [actual_year, last_year]: completed_subjects = [ { "subject_code": f"{subject['katedra']}/" f"{subject['zkratka']}", **subject, } for subject in subjects if ( subject.get("statut") == "A" or subject.get("statut") == "B" ) and int(subject["rok"]) != max_year ] else: completed_subjects = [ { "subject_code": f"{subject['katedra']}/" f"{subject['zkratka']}", **subject, } for subject in subjects if ( subject.get("statut") == "A" or subject.get("statut") == "B" ) ] # return only unique subjects because student could repeat the subject twice return list({s["subject_code"]: s for s in completed_subjects}.values()) def get_study_codes_for_active_studies(self, active_studies)-
Get study code for each active study
Args
active_studies list(dict): active studies
Returns
list(str): list of study codes
Expand source code
def get_study_codes_for_active_studies(self, active_studies): """Get study code for each active study Args: active_studies list(dict): active studies Returns: list(str): list of study codes """ study_codes = [] url = f"{STAG_BASE_URL}/student/getStudentInfo" for study in active_studies: params = dict(osCislo=study["osCislo"], outputFormat="json") try: response = self._send_get_request( url=url, params=params, auth=STAG_AUTH ) except requests.RequestException as err: raise StagUnavailableError() from err else: study_codes.append(response.get("kodSp")) return study_codes